package com.oromwin.repos.common;

import java.io.IOException;
import java.util.Properties;

import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.commons.logging.Log;

public enum ReposConfig {
    INSTANCE;
    @SuppressWarnings("unused")
    private final static Log log = Logger.getLog(ReposConfig.class);
    private static String _properties = null;
    // Database
    private static String _reposDatabaseDriver = null;
    private static String _reposDatabaseUri = null;
    private static String _reposDatabaseHost = null;
    private static int _reposDatabasePort = 0;
    private static String _reposDatabaseName = null;
    private static String _reposDatabaseUser = null;
    private static String _reposDatabasePasswd = null;
    private static int _reposDatabaseConnectTimeout = 0;
    // Local
    private static long _reposLocalDiskUsageReserved = 0;
    // Socket server
    private static String _reposSocketServerIP = "";
    private static int _reposSocketServerPort = 0;
    private static int _reposSocketServerPoolSize = 0;
    private static int _reposSocketIOBuffSize = 0;
    private static int _reposSocketServerTimeout = 0;
    // Socket client
    private static int _reposSocketClientTimeout = 0;
    // HTTP server
    private static String _reposHttpServerIP = "";
    private static int _reposHttpServerPort = 0;

    private ReposConfig() {
    }

    public static void initialize(String configPath) {
        _properties = configPath;
        loadProperties(_properties);
    }

    public static ReposConfig getInstance() {
        if (_properties == null) {
            loadProperties(Common.DEFAULT_PATH);
        }
        return INSTANCE;
    }

    public String getReposDatabaseDriver() {
        return _reposDatabaseDriver;
    }
    public String getReposDatabaseUri() {
        return _reposDatabaseUri;
    }
    public String getReposDatabaseHost() {
        return _reposDatabaseHost;
    }
    public int getReposDatabasePort() {
        return _reposDatabasePort;
    }
    public String getReposDatabaseName() {
        return _reposDatabaseName;
    }
    public String getReposDatabaseUser() {
        return _reposDatabaseUser;
    }
    public String getReposDatabasePasswd() {
        return _reposDatabasePasswd;
    }
    public int getReposDatabaseConnectTimeout() {
        return _reposDatabaseConnectTimeout;
    }
    public long getReposLocalDiskUsageReserved() {
        return _reposLocalDiskUsageReserved;
    }
    public String getReposSocketServerIP() {
        return _reposSocketServerIP;
    }
    public int getReposSocketPort() {
        return _reposSocketServerPort;
    }
    public int getReposSocketServerPoolSize() {
        return _reposSocketServerPoolSize;
    }
    public int getReposSocketIOBuffSize() {
        return _reposSocketIOBuffSize;
    }
    public int getReposSocketClientTimeout() {
        return _reposSocketClientTimeout;
    }
    public int getReposSocketServerTimeout() {
        return _reposSocketServerTimeout;
    }
    public String getReposHttpServerIP() {
        return _reposHttpServerIP;
    }
    public int getReposHttpServerPort() {
        return _reposHttpServerPort;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("-------------------- Repository Config --------------------\n");
        sb.append(String.format("repos.db.driver=%s\n", _reposDatabaseDriver));
        sb.append(String.format("repos.db.uri=%s\n", _reposDatabaseUri));
        sb.append(String.format("repos.db.host=%s\n", _reposDatabaseHost));
        sb.append(String.format("repos.db.port=%d\n", _reposDatabasePort));
        sb.append(String.format("repos.db.database=%s\n", _reposDatabaseName));
        sb.append(String.format("repos.db.user=%s\n", _reposDatabaseUser));
        sb.append(String.format("repos.db.passwd=%s\n", _reposDatabasePasswd));
        sb.append(String.format("repos.db.connect.timeout=%d\n", _reposDatabaseConnectTimeout));
        sb.append("\n");
        sb.append(String.format("repos.local.du.reserved=%d\n", _reposLocalDiskUsageReserved));
        sb.append("\n");
        sb.append(String.format("repos.socket.server.pool.size=%d\n", _reposSocketServerPoolSize));
        sb.append(String.format("repos.socket.io.buff.size=%d\n", _reposSocketIOBuffSize));
        sb.append(String.format("repos.socket.server.ip=%s\n", _reposSocketServerIP));
        sb.append(String.format("repos.socket.server.port=%d\n", _reposSocketServerPort));
        sb.append(String.format("repos.socket.server.timeout=%d\n", _reposSocketServerTimeout));
        sb.append(String.format("repos.socket.client.timeout=%d\n", _reposSocketClientTimeout));
        sb.append("\n");
        sb.append(String.format("repos.http.server.ip=%s\n", _reposHttpServerIP));
        sb.append(String.format("repos.http.server.port=%d\n", _reposHttpServerPort));
        sb.append("-------------------- Repository Config --------------------\n");
        return sb.toString();
    }

    private static void loadConfig(InputStream is) throws IOException, NumberFormatException {
        Properties p = new Properties();
        p.load(is);
        // Database
        _reposDatabaseDriver = p.getProperty("repos.db.driver");
        _reposDatabaseUri = p.getProperty("repos.db.uri");
        _reposDatabaseHost = p.getProperty("repos.db.host");
        _reposDatabasePort = Integer.parseInt(p.getProperty("repos.db.port"));
        _reposDatabaseName = p.getProperty("repos.db.database");
        _reposDatabaseUser = p.getProperty("repos.db.user");
        _reposDatabasePasswd = p.getProperty("repos.db.passwd");
        _reposDatabaseConnectTimeout = Integer.parseInt(p.getProperty("repos.db.connect.timeout"));
        // Local
        _reposLocalDiskUsageReserved = Long.parseLong(p.getProperty("repos.local.du.reserved"));
        // Socket
        _reposSocketServerPoolSize = Integer.parseInt(p.getProperty("repos.socket.server.pool.size"));
        _reposSocketIOBuffSize = Integer.parseInt(p.getProperty("repos.socket.io.buff.size"));
        _reposSocketServerIP = p.getProperty("repos.socket.server.ip");
        _reposSocketServerPort = Integer.parseInt(p.getProperty("repos.socket.server.port"));
        _reposSocketServerTimeout = Integer.parseInt(p.getProperty("repos.socket.server.timeout"));
        _reposSocketClientTimeout = Integer.parseInt(p.getProperty("repos.socket.client.timeout"));
        // HTTP
        _reposHttpServerIP = p.getProperty("repos.http.server.ip");
        _reposHttpServerPort = Integer.parseInt(p.getProperty("repos.http.server.port"));
    }

    /*
     * TODO
     * 1. write error log
     * 2. exit application
     * 3. throw ReposException.create(log, e.getMessage());
     */
    private static void loadProperties(String filepath) {
        InputStream is = null;
        try {
            is = new FileInputStream(filepath);
            loadConfig(is);
            is.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (NumberFormatException nfe) {
            nfe.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
